#ifndef __SCNS_IMAGE_H__
#define __SCNS_IMAGE_H__

#include "ScnsConfig.h"

#if defined(SCNS_IMAGE_ENABLE)&&SCNS_IMAGE_ENABLE==1

#include "ScnsYing.h"
#include "ScnsColor.h"

typedef struct
{
    ScnsColorFormat format;
    uint8 dynamic;
    uint16 width;
    uint16 height;
    void*p;
    union
    {
        ScnsColorArgb8888*clut;
        const ScnsColorArgb8888*__clut__;
    };
}ScnsImage;

#define scnsImageNewStatic(f,w,h,i,c)           (ScnsImage){.format=(f),.width=(w),.height=(h),.p=(void*)(uintptr_t)(i),.__clut__=(SCNS_COLOR_FORMAT_CLUT8==(f))?((c)?(c):(scnsColorRandomMap)):(NULL),.dynamic=0}
#define scnsImageIsSameSize(img1,img2)          ((img1)&&(img2)&&(img1)->width==(img2)->width&&(img1)->height==(img2)->height)
#define scnsImageSize(img)                      ((img)->width*(img)->height*((img)->format&0XF))

#define scnsImageGray8(img,x,y)                 (((ScnsColorGray8*)(img)->p)[(y)*(img)->width+(x)])
#define scnsImageClut8(img,x,y)                 (((ScnsColorClut8*)(img)->p)[(y)*(img)->width+(x)])
#define scnsImageBinary8(img,x,y)               (((ScnsColorBinary8*)(img)->p)[(y)*(img)->width+(x)])
#define scnsImageRGB565(img,x,y)                (((ScnsColorRgb565*)(img)->p)[(y)*(img)->width+(x)])
#define scnsImageARGB8888(img,x,y)              (((ScnsColorArgb8888*)(img)->p)[(y)*(img)->width+(x)])
#define scnsImageARGB4444(img,x,y)              (((ScnsColorArgb4444*)(img)->p)[(y)*(img)->width+(x)])

extern const ScnsImage*scnsImageGetARGB(const ScnsImage*img,uint16 x,uint16 y,uint8*a,uint8*r,uint8*g,uint8*b);
extern ScnsImage*scnsImageSetARGB(ScnsImage*img,uint16 x,uint16 y,uint8 a,uint8 r,uint8 g,uint8 b);
extern uint64 scnsImageMinus(const ScnsImage*src,const ScnsImage*dst);
#if defined(SCNS_MALLOC_ENABLE)&&SCNS_MALLOC_ENABLE==1
extern ScnsImage*scnsImageNew(ScnsColorFormat t,uint16 w,uint16 h);
extern ScnsImage*scnsImageFree(ScnsImage*img);
extern ScnsImage*scnsImagePress(const ScnsImage*src,uint16 rate,uint16 simpleRate);
extern ScnsImage*scnsImageMerge(const ScnsImage*imgA,const ScnsImage*imgR,const ScnsImage*imgG,const ScnsImage*imgB);
extern ScnsImage*scnsImageCut(const ScnsImage*src,Point lu,Point rd);

extern ScnsImage*scnsImageRotate(const ScnsImage*src,double angle,ScnsColorArgb8888 bgc,int upSample,Point points[],uint32 pointsLen);
extern ScnsImage*scnsImageTransform(const ScnsImage*src,FPoint (*transformer)(FPoint,const void*),const void*arg);

extern void scnsImageGetGrayMapByGamma(float y,float c,uint8 grayMap[256]);
extern ScnsImage*scnsImageGammaPlus(const ScnsImage*src,float luY,float ruY,float ldY);
extern ScnsImage*scnsImageGrayTransform(const ScnsImage*src,const uint8 grayMap[256]);

extern void scnsImageConvertToClut8(ScnsImage**inputImages,uint32 imageRow,uint8 imageCol,ScnsImage**outputImages,uint8 printDetail,uint8 maxDeep,uint16 maxColorCnt);
#endif
#endif

#endif